#include "Vector2.h"

namespace _Warp
{
	const Vector2 Vector2::Zero = Vector2();

	Vector2::Vector2(const Scalar x,const Scalar y)
	{
		X = x;
		Y = y;
	}

	Vector2::~Vector2()
	{
	}

	void Vector2::operator+=(const Vector2& pVector)
	{
		X += pVector.X;
		Y += pVector.Y;
	}

	void Vector2::operator-=(const Vector2& pVector)
	{
		X -= pVector.X;
		Y -= pVector.Y;
	}

	void Vector2::operator*=(const Scalar& num)
	{
		X *= num;
		Y *= num;
	}

	void Vector2::operator/=(const Scalar& num)
	{
		X /= num;
		Y /= num;
	}

	void Vector2::operator=(const Vector2& pVector)
	{
		X = pVector.X;
		Y = pVector.Y;
	}

	Scalar Vector2::Length() const
	{
		return sqrt(pow(X,2.0f) + pow(Y,2.0f));
	}

	void Vector2::Clamp(const Scalar& value)
	{
		if(Length() <= value)
			return;
		Normalize();
		*this *= value;
	}

	void Vector2::Normalize(const Scalar& value)
	{
		Scalar vecLength = Length();

		if(vecLength == 0)
			return;

		X = X/vecLength * value;
		Y = Y/vecLength * value;
	}

	void Vector2::Invert()
	{
		X *= -1;
		Y *= -1;
	}

	Vector2 Vector2::Polar(const Scalar& x,const Scalar& y)
	{
		Vector2 pVector = Vector2();
		pVector.X = atan2(y,x);
		pVector.Y = sqrt(x * x + y * y);
		return pVector;
	}

	Vector2 Vector2::Cartesian(const Scalar& radius,const Scalar& angle)
	{
		Vector2 pVector = Vector2();
		pVector.X = radius * cos(angle);
		pVector.Y = radius * sin(angle);
		return pVector;
	}

	Scalar Vector2::Dot(const Vector2& pVec1,const Vector2& pVec2)
	{
		return pVec1.X * pVec2.X + pVec1.Y * pVec2.Y;
	}

	Vector2 Vector2::Rotate(const Vector2& pVec,const Scalar& angle)
	{
		Scalar cosResult = cos(angle);
        Scalar sinResult = sin(angle);

        //Essentially, apply a 2x2 rotation matrix to the vector
		Scalar newX = pVec.X * cosResult - pVec.Y * sinResult;
        Scalar newY = pVec.X * sinResult + pVec.Y * cosResult;

        return Vector2(newX,newY);
	}
}
